package com.sencorsta.ids.core.application.master;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.sencorsta.ids.core.application.Application;
import com.sencorsta.ids.core.application.master.callback.GetTotalServerCallback;
import com.sencorsta.ids.core.application.proxy.ProxyClient;
import com.sencorsta.ids.core.application.proxy.push.TotalServerPush;
import com.sencorsta.ids.core.configure.*;
import com.sencorsta.ids.core.entity.Server;
import com.sencorsta.ids.core.function.FunctionSystem;
import com.sencorsta.ids.core.function.SynFunction;
import com.sencorsta.ids.core.log.Out;
import com.sencorsta.ids.core.tcp.socket.NetHandler;
import com.sencorsta.ids.core.tcp.socket.client.RpcClientBootstrap;
import com.sencorsta.ids.core.tcp.socket.client.RpcClientChannelHandler;
import com.sencorsta.ids.core.tcp.socket.client.RpcClientWorker;
import com.sencorsta.ids.core.tcp.socket.coder.RpcCodecFactory;
import com.sencorsta.ids.core.tcp.socket.protocol.RpcMessage;

/**
 * 　　* @description: 主客户端
 * 　　* @author TAO
 * 　　* @date 2019/6/12 17:28
 *
 */
public class MasterClient extends RpcClientWorker {
    public Server localServer;

    private static MasterClient instance = null;
    public volatile boolean isAlert = false;

    // 接收回调用
    private MasterDispatcher __dispacher__=new MasterDispatcher("MasterClient");

    public static MasterClient getInstance() {
        if (instance == null) {
            instance = new MasterClient();
        }
        return instance;
    }
    @Override
    public void messageReceive(RpcMessage message) {
        __dispacher__.execute(message);
        //Application.getInstance().addReceiveToDispatcher(message);
    }
    @Override
    public void ping() {
        Out.trace("开始向master发送PingMaster!");
        RpcMessage message = new RpcMessage(TypeProtocol.TYPE_RPC_REQ);
        message.method = "PingMaster";
        message.serializeType = TypeSerialize.TYPE_JSON;
        JSONObject req = new JSONObject();
        req.put("freeMemory", FunctionSystem.getFreeMemoryMB());
        message.data = JSON.toJSONString(req).getBytes(GlobalConfigure.UTF_8);
        MasterClient.getInstance().addSend(message);
    }

    @Override
    public void doStart() {
        RpcMessage message = new RpcMessage(TypeProtocol.TYPE_RPC_REQ);
        message.method = "JoinMaster";
        message.serializeType = TypeSerialize.TYPE_JSON;

        SysConfig config = SysConfig.getInstance();

        if (localServer == null) {
            localServer = new Server();
            localServer.type = Application.SERVER_TYPE;

            localServer.openHost = config.get("openServer.host", "0.0.0.0");
            localServer.openPublicHost = config.get("openServer.host.public", localServer.openHost);
            localServer.openPort = config.getInt("openServer.port", 0);
            localServer.backHost = config.get("service.host", "0.0.0.0");
            localServer.backPublicHost = config.get("service.host.public", localServer.backHost);
            localServer.backPort = config.getInt("service.port", 0);
            localServer.freeMemory = (int) FunctionSystem.getFreeMemoryMB();
            localServer.maxMemory = (int) FunctionSystem.getMaxMemoryMB();
        }
        message.data = JSON.toJSONString(localServer).getBytes(GlobalConfigure.UTF_8);
        message.channel = channel;
        RpcMessage response = SynFunction.request(message);

        JSONObject json = JSON.parseObject(new String(response.data));
        if (json.containsKey("code") && json.getInteger("code") == 0) {
            String sid = json.getJSONObject("data").getString("sid");
            MasterClient.getInstance().localServer.sid = sid;
            Out.info("注册master成功啦😀!", "sid:", sid);
        } else {
            MasterClient.getInstance().close(channel);
            Out.info("注册master失败😭: ", json);
        }
    }


    public void getTotalServer() {
        Out.trace("开始向master发送getTotalServer!");
        RpcMessage message = new RpcMessage(TypeProtocol.TYPE_RPC_REQ);
        message.method = "GetTotalServer";
        message.serializeType = TypeSerialize.TYPE_JSON;
        JSONObject req = new JSONObject();
        req.put("freeMemory", FunctionSystem.getFreeMemoryMB());
        message.data = JSON.toJSONString(req).getBytes(GlobalConfigure.UTF_8);

        MasterClient.getInstance().addSend(message);

//		message.channel=channel;
//		RpcMessage response= SynFunction.request(message);
//
//		JSONObject json=JSON.parseObject(new String(response.data));
//		ProxyClient.maintenanceList(json.getJSONObject("data").getJSONObject("totalServers"));
    }

    public MasterClient() {
        this.bootstrap = new RpcClientBootstrap("Master",new RpcCodecFactory(new RpcClientChannelHandler(this)));
        this.serverHost = SysConfig.getInstance().get("server.master.host");
        this.serverPort = SysConfig.getInstance().getInt("server.master.port", 0);


        __dispacher__.registerHandler(new TotalServerPush());
        __dispacher__.registerHandler(new GetTotalServerCallback());
        // new Thread(__dispacher__, String.format("master<-%s:%d", serverHost,
        // serverPort)).start();
        // super.start();
    }

    public void start() throws Exception {
        // GGame.getInstance().onWorkerBefore(this);
        // bind(bootstrap.connect(serverHost, serverPort));
        // new Thread(__dispacher__, String.format("%s->%s:%d", name, serverHost,
        // serverPort)).start();
        super.start();
    }

    public void registerCallBackHandler(NetHandler handler) {
        Application.getInstance().registerHandler(handler);
    }

}
